/*
 * Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
 * All rights reserved
 */

#ifndef _MULTI_BUTTON_H_
#define _MULTI_BUTTON_H_

#include "stdint.h"
#include "string.h"

//According to your need to modify the constants.
#define TICKS_INTERVAL    5	//ms
#define DEBOUNCE_TICKS    3	//MAX 8
#define SHORT_TICKS       (300 /TICKS_INTERVAL)
#define LONG_TICKS        (1000 /TICKS_INTERVAL)


typedef void (*BtnCallback)(void*);

typedef enum {
	PRESS_DOWN = 0,  //按下触发
	PRESS_UP,        //抬起触发
	PRESS_REPEAT,    //按下计数
	SINGLE_CLICK,    //单击触发
	DOUBLE_CLICK,    //双击触发
	LONG_PRESS_START,//长按开始
	LONG_PRESS_HOLD, //长按触发
	number_of_event, //事件数量
	NONE_PRESS       //按键空闲
}PressEvent;

typedef struct Button {
	uint16_t ticks;            		                   //按下时间计数
	uint8_t  repeat : 4;       		                   //重复计数
	uint8_t  event : 4;           	                   //按键事件
	uint8_t  state : 3;                                //状态机状态位
	uint8_t  debounce_cnt : 3;                         //双击计数
	uint8_t  active_level : 1;                         //按键触发的电平
	uint8_t  button_level : 1;                         //滤波后按键电平
    uint8_t  button_id;                                //按键id
	uint8_t  (*hal_button_Level)(uint8_t button_id);   //返回按键电平函数
	BtnCallback  cb[number_of_event];                  //回调函数
	struct Button* next;                               //链表指针
}Button;

#ifdef __cplusplus
extern "C" {
#endif

void button_init(struct Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id);
void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);
PressEvent get_button_event(struct Button* handle);
int  button_start(struct Button* handle);
void button_stop(struct Button* handle);
void button_ticks(void);

#ifdef __cplusplus
}
#endif

#endif
